package datatypes.r2.foundation.impl;

import datatypes.r2.flavors.ST_SIMPLE;
import datatypes.r2.foundation.BAG;
import datatypes.r2.foundation.DSET;
import datatypes.r2.quantities.INT;

/**
 * An unordered collection of values, where any value can occur more than once.
 * 
 * @author Obama
 * 
 * @param <T>
 */
public class Bag<T> extends Collection<T> implements BAG<T> {

	private static final long serialVersionUID = 1L;

	public Bag() {
		super();
	}

	public static long getSerialversionuid() {
		return serialVersionUID;
	}

	/**
	 * The number of items in this bag with the given item value.
	 * 
	 */
	@Override
	public INT count(T item) {
		// TODO
		return null;
	}

	/**
	 * A BAG that contains all items of the operand BAGs.
	 */
	@Override
	public BAG<T> plus(BAG<T> x) {
		
		return plusBag(x);
	}

	/**
	 * only if Bag's plus implements
	 * 
	 * @param x
	 * @return
	 */
	private BAG<T> plusBag(BAG<T> x) {
		if (x instanceof Bag) {
			Bag<T> bag = (Bag<T>) x;
			getList().addAll(bag.getList());
		}
		return this;
	}

	/**
	 * A BAG that contains all items of this BAG (minuend) diminished by the
	 * items in the other BAG (subtrahend). BAGs cannot carry deficits: When the
	 * subtrahend contains more items of one value than the minuend, the
	 * difference contains zero items of that value.A BAG that contains all
	 * items of this BAG (minuend) diminished by the items in the other BAG
	 * (subtrahend). BAGs cannot carry deficits: When the subtrahend contains
	 * more items of one value than the minuend, the difference contains zero
	 * items of that value.
	 */
	@Override
	public BAG<T> minus(BAG<T> x) {

		return minusBag(x);
	}

	/**
	 * only if Bag's minus implements
	 * 
	 * @param x
	 * @return
	 */
	private BAG<T> minusBag(BAG<T> x) {

		if (x instanceof Bag) {
			Bag<T> bag = (Bag<T>) x;
			getList().removeAll(bag.getList());
		}
		return this;
	}

	@Override
	public ST_SIMPLE literal() {
		// TODO Auto-generated method stub
		return null;
	}

	/**
	 * A data value of type T can be promoted into a trivial BAG of type T with
	 * that data value as its only item.
	 */
	@Override
	public BAG<T> promotion(T x) {
		getList().clear();
		getList().add(x);
		return this;
	}

	/**
	 * A discrete set of items can be promoted into a BAG that contains the same
	 * items. No items are lost during the promotion.
	 */
	@Override
	public BAG<T> promotion(DSET<T> x) {
		return null;
	}

}
